package com.gimc.evil.config

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.json.PackageVersion
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.{JsonSerializer, ObjectMapper, SerializerProvider}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.springframework.context.ApplicationListener
import org.springframework.context.annotation.{Bean, Configuration}
import org.springframework.web.context.request.async.DeferredResult
import springfox.documentation.builders.{ApiInfoBuilder, RequestHandlerSelectors}
import springfox.documentation.schema.configuration.ObjectMapperConfigured
import springfox.documentation.service.ApiInfo
import springfox.documentation.spi.DocumentationType
import springfox.documentation.spring.web.plugins.Docket
import springfox.documentation.swagger2.annotations.EnableSwagger2

/**
 *
 * @author yin.he
 */
@Configuration
@EnableSwagger2
class SwaggerConfig {

  @Bean
  def userDocketFactory: Docket = {
    val docket = new Docket(DocumentationType.SWAGGER_2)
      .apiInfo(apiInfo)
      .groupName("redis-del")
      .select()
      .apis(RequestHandlerSelectors.basePackage("com.gimc.evil.controller"))
      .build()
      .useDefaultResponseMessages(true)
    docket.enable(true)
  }

  def apiInfo: ApiInfo = {
    new ApiInfoBuilder()
      .title("Spring Boot Using Scala With Swagger")
      .description("redis rest API")
      .version("1.0")
      .build()
  }

  @Bean
  def objectMapperInitializer = new ApplicationListener[ObjectMapperConfigured] {
    def onApplicationEvent(event: ObjectMapperConfigured) = {
      event.getObjectMapper.registerModule(DefaultScalaModule)
      val newModule = new SimpleModule(PackageVersion.VERSION)
      newModule.addSerializer(classOf[DeferredResult[_]], new DeferredResultSerializer(event.getObjectMapper))
      event.getObjectMapper.registerModule(newModule)
    }
  }
}

class DeferredResultSerializer(objectMapper: ObjectMapper) extends JsonSerializer[DeferredResult[_]] {

  override def serialize(value: DeferredResult[_], gen: JsonGenerator, serializers: SerializerProvider) = {
    gen.writeString(objectMapper.writeValueAsString(value.getResult))
  }
}
